package edu.uj.petri.view;

import edu.uj.util.Observer;
import edu.uj.util.ObserverList;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;

/**
 * @author Pawel
 */
public class StandardView implements View {

    private List<DiagramElement> elements;
    private transient Set<DiagramElement> selectedElements;
    private transient Canvas canvas;
    private transient ObserverList observerList;
    
    public StandardView( ) {
        elements = new LinkedList<DiagramElement>();
        selectedElements = new HashSet<DiagramElement>();
        observerList = new ObserverList();
    }
    
    public DiagramElement getClickedElement(Point2D point, boolean nodeonly) {
               
        // trawers wstecz        
        ListIterator<DiagramElement> i = elements.listIterator(elements.size());
        List<DiagramElement> arcs = new LinkedList<DiagramElement>();
        
        DiagramElement e;
        
        while (i.hasPrevious()) 
            if ((e = i.previous()).containsPoint(point))
                if (e instanceof NodeView) return e;
                else arcs.add( e );
        
        if ((!nodeonly) && (!arcs.isEmpty()))
            return arcs.get(0);
            
        
        
        return null;
    }

    public void selectNone()
    {
        for (DiagramElement e : selectedElements) e.setSelected( false );
        selectedElements.clear();
    }
    
    public void clickSelectableElement( DiagramElement elm )
    {
        selectNone();
        elm.setSelected(true);
        selectedElements.add(elm);
    }
    
    public void addElement(DiagramElement elm) {
        
        elements.add(elm);
        elm.subscribe(this);
    }

    public void draw() {
        
        if (canvas == null) return;
        
        canvas.clear();
        
        List<DiagramElement> nodes = new LinkedList<DiagramElement>();
        
        for (DiagramElement e : elements)
            if (!e.removed) 
                if (e instanceof NodeView) nodes.add( e );
                else e.draw(canvas);
        
        // zeby wezly byly na wierzchu        
        for (DiagramElement e : nodes ) e.draw(canvas);            
    }

    public void removeElement(DiagramElement elm) {
        elements.remove(elm);
        selectedElements.remove(elm);
        elm.unsubscribe(this);
       // elm.removeFrom(this);
        draw();
    }

    public void subscribe(Observer o) {
        observerList.subscribe(o);
    }

    public void unsubscribe(Observer o) {
        observerList.unsubscribe(o);
    }

    public void notifyFromObserved(int eventCode) {
        switch (eventCode) {
            case DiagramElement.REDRAW:
                draw();
                break;
        }
    }

    public void setCanvas(Canvas canvas) {
        
        this.canvas = canvas;
    }
    
    public Canvas getCanvas() {
        
        return canvas;
    }
    
    private void readObject(java.io.ObjectInputStream in)
    throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        
        observerList = new ObserverList();
        selectedElements = new HashSet<DiagramElement>();
    }
    
    private static final long serialVersionUID = -9223201196923467825L;
}
